/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jps.envs;

import java.util.ArrayList;
import java.util.List;
import jps.datastore.ComplexObject;
import jps.datastore.SBAObject;
import jps.datastore.SBAStore;
import jps.datastore.SimpleObject;
import jps.main.Main;
import jps.qres.*;

/**
 *
 * @author calyJa
 */
public class ENVS {

    private List<ENVSStackFrame> stack;

    public void init(Long rootOID) {
        SBAStore sbaStore = Main.sbaStore;
        ENVSStackFrame frame = new ENVSStackFrame();
        ComplexObject root = (ComplexObject) sbaStore.getObject(rootOID);
        for (Long childOID : root.getChildOIDs()) {
            SBAObject sbaObject = sbaStore.getObject(childOID);
            ENVSBinder binder = new ENVSBinder(sbaObject.getName(), new ReferenceResult(childOID));
            frame.add(binder);
        }

        stack = new ArrayList<ENVSStackFrame>();
        stack.add(frame);
    }

    public ENVSStackFrame pop() {
        ENVSStackFrame removedFrame = stack.remove(stack.size() - 1);
        return removedFrame;
    }

    public void push(ENVSStackFrame frame) {
        stack.add(frame);
    }

    public BagResult bind(String name) {
        for (int i = stack.size() - 1; i >= 0; i--) {
            ENVSStackFrame frame = stack.get(i);
            BagResult bagResult = frame.get(name);
            if (bagResult != null) {
                return bagResult;
            }
        }
        return null;
    }

    public List<ENVSBinder> nested(AbstractQueryResult result, SBAStore store) {
        List<ENVSBinder> binders = new ArrayList<ENVSBinder>();

        if (result instanceof ReferenceResult) {
            Long oid = ((ReferenceResult) result).getOID();
            SBAObject referencedObject = store.getObject(oid);
            if (referencedObject instanceof ComplexObject) {
                ComplexObject object = (ComplexObject) referencedObject;
                for (Long childOID : object.getChildOIDs()) {
                    SBAObject child = store.getObject(childOID);
                    String name = child.getName();
                    ReferenceResult refRes = new ReferenceResult(childOID);
                    binders.add(new ENVSBinder(name, refRes));
                }
            } else if (referencedObject instanceof SimpleObject) {
                binders.add(new ENVSBinder(referencedObject.getName(), new ReferenceResult(oid)));
            }
        } else if (result instanceof BinderResult) {
            binders.add(new ENVSBinder(((BinderResult) result).getName(), ((BinderResult) result).getValue()));
        } else if (result instanceof BagResult) {
            for (AbstractQueryResult currentResult : ((BagResult) result).getElements()) {
                List<ENVSBinder> currentResultBinders = nested(currentResult, store);
                if (currentResultBinders != null) {
                    binders.addAll(currentResultBinders);
                }
            }
        } else if (!(result instanceof BooleanResult || result instanceof IntegerResult || result instanceof RealResult
                || result instanceof StringResult)) {
            binders = null;
        }

        return binders;
    }

}